﻿#include <stdlib.h>
#include <stdio.h>
//
//struct HeapMetadata {
//    size_t BlockSize;     // 块大小
//    unsigned int Flags;  // 分配标志
//    int Previous;       // 前一个块的指针
//    int Next;           // 后一个块的指针
//};
//
//#include <Windows.h>
///* Core heap definitions */
//#define HEAP_SEGMENTS 64
//
//#define HEAP_ENTRY_SIZE ((ULONG)sizeof(HEAP_ENTRY))
//#ifdef _WIN64
//#define HEAP_ENTRY_SHIFT 4
//#else
//#define HEAP_ENTRY_SHIFT 3
//#endif
//#define HEAP_MAX_BLOCK_SIZE ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
//
//#define ARENA_INUSE_FILLER     0xBAADF00D
//#define ARENA_FREE_FILLER      0xFEEEFEEE
//#define HEAP_TAIL_FILL         0xab
//
//// from ntifs.h, should go to another header!
//#define HEAP_GLOBAL_TAG                 0x0800
//#define HEAP_PSEUDO_TAG_FLAG            0x8000
//#define HEAP_TAG_MASK                  (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
//#define HEAP_TAGS_MASK                 (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT))
//
//#define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \
//                               HEAP_SETTABLE_USER_VALUE | \
//                               HEAP_TAGS_MASK)
//
///* Heap entry flags */
//#define HEAP_ENTRY_BUSY           0x01
//#define HEAP_ENTRY_EXTRA_PRESENT  0x02
//#define HEAP_ENTRY_FILL_PATTERN   0x04
//#define HEAP_ENTRY_VIRTUAL_ALLOC  0x08
//#define HEAP_ENTRY_LAST_ENTRY     0x10
//#define HEAP_ENTRY_SETTABLE_FLAG1 0x20
//#define HEAP_ENTRY_SETTABLE_FLAG2 0x40
//#define HEAP_ENTRY_SETTABLE_FLAG3 0x80
//#define HEAP_ENTRY_SETTABLE_FLAGS (HEAP_ENTRY_SETTABLE_FLAG1 | HEAP_ENTRY_SETTABLE_FLAG2 | HEAP_ENTRY_SETTABLE_FLAG3)
//
///* Signatures */
//#define HEAP_SIGNATURE         0xeefeeff
//#define HEAP_SEGMENT_SIGNATURE 0xffeeffee
//
///* Segment flags */
//#define HEAP_USER_ALLOCATED    0x1
//
//typedef struct _HEAP_COMMON_ENTRY
//{
//#ifdef _M_AMD64
//    PVOID PreviousBlockPrivateData;
//#endif
//    union
//    {
//        struct
//        {
//            USHORT Size;
//            UCHAR Flags;
//            UCHAR SmallTagIndex;
//        };
//        struct
//        {
//#ifndef _M_AMD64
//            PVOID SubSegmentCode;
//#else
//            ULONG SubSegmentCodeDummy;
//#endif
//            USHORT PreviousSize;
//            union
//            {
//                UCHAR SegmentOffset;
//                UCHAR LFHFlags;
//            };
//            UCHAR UnusedBytes;
//        };
//        struct
//        {
//            USHORT FunctionIndex;
//            USHORT ContextValue;
//        };
//        struct
//        {
//            ULONG InterceptorValue;
//            USHORT UnusedBytesLength;
//            UCHAR EntryOffset;
//            UCHAR ExtendedBlockSignature;
//        };
//        struct
//        {
//            ULONG Code1;
//            USHORT Code2;
//            UCHAR Code3;
//            UCHAR Code4;
//        };
//        ULONGLONG AgregateCode;
//    };
//}HEAP_COMMON_ENTRY;
//
//typedef struct _HEAP_ENTRY_EXTRA
//{
//    union
//    {
//        struct
//        {
//            USHORT AllocatorBackTraceIndex;
//            USHORT TagIndex;
//            ULONG_PTR Settable;
//        };
//        UINT64 ZeroInit;
//    };
//} HEAP_ENTRY_EXTRA, * PHEAP_ENTRY_EXTRA;
//
//typedef struct _HEAP_ENTRY
//{
//    struct _HEAP_COMMON_ENTRY;
//}  HEAP_ENTRY, * PHEAP_ENTRY;
//
//typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY
//{
//    LIST_ENTRY Entry;
//    HEAP_ENTRY_EXTRA ExtraStuff;
//    SIZE_T CommitSize;
//    SIZE_T ReserveSize;
//    HEAP_ENTRY BusyBlock;
//} HEAP_VIRTUAL_ALLOC_ENTRY, * PHEAP_VIRTUAL_ALLOC_ENTRY;
//
//SIZE_T NTAPI RtlpGetSizeOfBigBlock(HEAP_COMMON_ENTRY* 	HeapEntry)
//{
//    PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
//
//    /* Get pointer to the containing record */
//    VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
//    //ASSERT(VirtualEntry->BusyBlock.Size >= sizeof(HEAP_VIRTUAL_ALLOC_ENTRY));
//
//    /* Restore the real size */
//    return VirtualEntry->CommitSize - HeapEntry->Size;
//}

//void cause_heap_corruption() {
//    int* ptr1 = (int*)malloc(sizeof(int) * 4 + 3);
//    char* ptr2 = (char*)malloc(sizeof(char) * 5);
//
//    int count = 0x0F * 2;
//    char* ptr3 = (char*)malloc(count);
//
//
//    for (int i = 0; 4 > i; i++) {  // 错误：越界写入
//        ptr1[i] = -1;
//        ptr2[i] = 'a';
//        ptr3[i] = 'b';
//    }
//
//    int uSize = sizeof(struct _HEAP_COMMON_ENTRY);
//
//    struct HeapMetadata* data1 = (struct HeapMetadata*)((char* )ptr1 - sizeof(struct HeapMetadata));
//    struct HeapMetadata* data2 = (struct HeapMetadata*)(ptr2 - sizeof(struct HeapMetadata));
//    struct HeapMetadata* data3 = (struct HeapMetadata*)(ptr3 - sizeof(struct HeapMetadata));
//
//    intptr_t diff1 = (intptr_t)ptr2 - (intptr_t)ptr1;
//    intptr_t diff2 = (intptr_t)ptr3 - (intptr_t)ptr2;
//
//    HEAP_COMMON_ENTRY* entry1 = (HEAP_COMMON_ENTRY*)((char*)ptr1 - sizeof(HEAP_COMMON_ENTRY));
//    HEAP_COMMON_ENTRY* entry2 = (HEAP_COMMON_ENTRY*)((char*)ptr2 - sizeof(HEAP_COMMON_ENTRY));
//    HEAP_COMMON_ENTRY* entry3 = (HEAP_COMMON_ENTRY*)((char*)ptr3 - sizeof(HEAP_COMMON_ENTRY));
//
//    int EntrySize = 0;
//    if (entry1->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
//    {
//        EntrySize = RtlpGetSizeOfBigBlock(entry1);
//    }
//    else
//    {
//        /* Calculate it */
//        EntrySize = (entry1->Size << HEAP_ENTRY_SHIFT) - entry1->UnusedBytes;
//    }
//
//
//
//    free(ptr2);
//
//    
//}

int mem() {
    char* p = (char* )malloc(10);
    p[11] = 'a';
    return 0;
}

extern "C" int a  = mem();

int main() {
    char* p = (char*)malloc(14);
    free(p);
    p[0] = 'a';
    return 0;
}

